vue3
<!-- author: xuett -->
<!-- date: 2025-07-07 16:06:18 -->
<!-- description:  -->
<template>
  <div class="chart-box">
    <v-chart ref="chart2" :option="chart2Option" autoresize @mouseover="chart2Mouseover" @mouseout="chart2Mouseout" />
  </div>
</template>

<script setup>
import * as echarts from "echarts";

const state = reactive({
  card2Data: [
    {
      name: "吕梁",
      valueList: {
        jd: 5,
        cy: 16,
        zs: 7,
        tcc: 8,
        yz: 9,
        wsj: 12
      }
    },
    {
      name: "临汾",
      valueList: {
        jd: 12,
        cy: 16,
        zs: 7,
        tcc: 9,
        yz: 12,
        wsj: 23
      }
    },
    {
      name: "阳泉",
      valueList: {
        jd: 9,
        cy: 12,
        zs: 18,
        tcc: 30,
        yz: 6,
        wsj: 30
      }
    },
    {
      name: "晋中",
      valueList: {
        jd: 15,
        cy: 18,
        zs: 21,
        tcc: 24,
        yz: 12,
        wsj: 23
      }
    },
    {
      name: "长治",
      valueList: {
        jd: 10,
        cy: 19,
        zs: 16,
        tcc: 25,
        yz: 9,
        wsj: 13
      }
    },
    {
      name: "晋城",
      valueList: {
        jd: 19,
        cy: 17,
        zs: 25,
        tcc: 24,
        yz: 30,
        wsj: 27
      }
    },
    {
      name: "朔州",
      valueList: {
        jd: 18,
        cy: 16,
        zs: 13,
        tcc: 17,
        yz: 22,
        wsj: 25
      }
    },
    {
      name: "忻州",
      valueList: {
        jd: 17,
        cy: 19,
        zs: 21,
        tcc: 22,
        yz: 14,
        wsj: 13
      }
    },
    {
      name: "太原",
      valueList: {
        jd: 16,
        cy: 21,
        zs: 24,
        tcc: 16,
        yz: 22,
        wsj: 23
      }
    },
    {
      name: "大同",
      valueList: {
        jd: 18,
        cy: 12,
        zs: 17,
        tcc: 21,
        yz: 12,
        wsj: 23
      }
    },
    {
      name: "运城",
      valueList: {
        jd: 12,
        cy: 12,
        zs: 12,
        tcc: 12,
        yz: 12,
        wsj: 23
      }
    }
  ],
  chart2Option: {},
  chart2Select: {
    isSet: false,
    currentIndex: 0
  }
});
const { chart2Option } = toRefs(state);

onMounted(() => {
  initChart();
});

//配套系统
const chart2 = ref();
const initChart = () => {
  let barList = [
    {
      name: "景点",
      prop: "jd",
      color: ["#303866", "#5B6AC2"]
    },
    {
      name: "餐饮",
      prop: "cy",
      color: ["#3B5736", "#8ACE7D"]
    },
    {
      name: "住宿",
      prop: "zs",
      color: ["#7C6533", "#F9CB66"]
    },
    {
      name: "停车场",
      prop: "tcc",
      color: ["#853A3B", "#F06869"]
    },
    {
      name: "驿站",
      prop: "yz",
      color: ["#345664", "#73BEDC"]
    },
    {
      name: "卫生间",
      prop: "wsj",
      color: ["#153E7F", "#226EE9"]
    }
  ];
  state.chart2Option = {
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow" // 默认为直线，可选为：'line' | 'shadow'
      },
      textStyle: {
        color: "#fff",
        fontSize: 12
      },
      backgroundColor: "#255DA9"
    },
    grid: {
      top: "9%",
      left: "3%",
      right: "0",
      bottom: "0%",
      containLabel: true
    },
    legend: {
      data: barList.map((item) => {
        return {
          name: item.name,
          itemStyle: {
            color: item.color[1]
          }
        };
      }),
      top: "3%",
      itemWidth: 10,
      itemHeight: 10,
      itemGap: 20,
      textStyle: {
        color: "#ffffff",
        fontSize: 14
      }
    },
    xAxis: [
      {
        type: "value",
        splitLine: {
          show: false
        },
        axisTick: {
          show: false
        },
        axisLine: {
          show: false
        },
        axisLabel: {
          show: false
        }
      }
    ],
    yAxis: [
      {
        type: "category",
        inverse: true,
        axisLine: {
          lineStyle: {
            color: "#263F70"
          }
        },
        axisTick: {
          show: false
        },
        axisLabel: {
          show: true,
          textStyle: {
            fontSize: 18,
            color: "#fff"
            // fontWeight: "bold"
          },
          margin: 15
        },
        data: state.card2Data.map((item) => item.name)
      }
    ],
    color: barList.map((item) => item.color[1]),
    series: barList.map((barItem) => {
      return {
        name: barItem.name,
        type: "bar",
        barWidth: 20,
        stack: "value",
        barGap: 31,
        data: state.card2Data.map((item) => item.valueList[barItem.prop]),
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
            {
              offset: 0,
              color: barItem.color[0] //结束颜色
            },
            {
              offset: 1,
              color: barItem.color[1] // 起始颜色
            }
          ])
        },
        label: {
          show: true,
          position: "insideRight"
        }
      };
    })
  };
  if (chart2Timer) {
    clearInterval(chart2Timer);
    chart2Timer = null;
  }
  chart2Timer = setInterval(chart2Hover, 1500);
};
var chart2Timer = null;
const chart2Mouseover = (param) => {
  state.chart2Select.isSet = false;
  if (chart2Timer) {
    clearInterval(chart2Timer);
    chart2Timer = null;
  }
  // 取消之前高亮的图形
  chart2.value.dispatchAction({
    type: "downplay",
    seriesIndex: 0,
    dataIndex: state.chart2Select.currentIndex
  });
  // 高亮当前图形
  chart2.value.dispatchAction({
    type: "highlight",
    seriesIndex: 0,
    dataIndex: param.dataIndex
  });
  // 显示 tooltip
  chart2.value.dispatchAction({
    type: "showTip",
    seriesIndex: 0,
    dataIndex: param.dataIndex
  });
  state.chart2Select.currentIndex = param.dataIndex;
};

// 3、自动高亮展示
const chart2Hover = function () {
  if (!chart2.value) {
    return;
  }
  var dataLen = state.chart2Option.series[0].data.length;
  // 取消之前高亮的图形
  chart2.value.dispatchAction({
    type: "downplay",
    seriesIndex: 0,
    dataIndex: state.chart2Select.currentIndex
  });
  state.chart2Select.currentIndex = (state.chart2Select.currentIndex + 1) % dataLen;
  // 高亮当前图形
  chart2.value.dispatchAction({
    type: "highlight",
    seriesIndex: 0,
    dataIndex: state.chart2Select.currentIndex
  });
  // 显示 tooltip
  chart2.value.dispatchAction({
    type: "showTip",
    seriesIndex: 0,
    dataIndex: state.chart2Select.currentIndex
  });
};
//鼠标移出之后，恢复自动高亮
const chart2Mouseout = () => {
  if (!state.chart2Select.isSet) {
    if (chart2Timer) {
      clearInterval(chart2Timer);
      chart2Timer = null;
    }
    chart2Timer = setInterval(chart2Hover, 2000);
    state.chart2Select.isSet = true;
  }
};
</script>

<style scoped lang="scss">
.chart-box {
  width: 100%;
  height: 100%;
  padding: 15px;
  background-color: #000;
}
</style>
